function isFunction(value) {
  return typeof value === "function";
}

function isVnode(ctx, scope) {
  return scope.constructor.name == ctx.parent.$vnode.constructor.name;
}

function findSlot(ctx, slotName) {
  const ctxSlot = ctx.scopedSlots[slotName.toLowerCase()];
  if (isFunction(ctxSlot)) {
    return ctxSlot;
  }
  let parent = ctx.parent;
  while (parent) {
    if (isFunction(parent.$scopedSlots?.[slotName])) {
      return parent.$scopedSlots[slotName];
    } else {
      parent = parent.$parent;
    }
  }
  return null;
}

export default {
  name: "ZBuilder",
  functional: true,
  props: {
    name: {
      type: [Function, String, Object],
      default: "",
    },
  },
  render: (h, ctx) => {
    const scope = ctx.props.name;
    if (isVnode(ctx, scope)) return scope;
    if (isFunction(scope)) {
      return scope(h, ctx.data.attrs, ctx.listeners);
    }
    if (scope && typeof scope === "string") {
      ctx._slot = ctx._slot || findSlot(ctx, scope);
      if (ctx._slot) {
        return ctx._slot(ctx.data.attrs);
      }
    }
    return h(null);
  },
};
